package com.lfs.market.controller.admin;

import cn.hutool.core.lang.UUID;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.lfs.market.common.Result;
import com.lfs.market.listener.UserInfoReadListener;
import com.lfs.market.model.entity.Orders;
import com.lfs.market.model.entity.ProductInfo;
import com.lfs.market.model.entity.User;
import com.lfs.market.model.vo.OrderExcelVo;
import com.lfs.market.model.vo.UserExcelVo;
import com.lfs.market.service.OrdersService;
import com.lfs.market.service.ProductInfoService;
import com.lfs.market.service.UserService;
import com.lfs.market.utils.BeanCopyUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/admin")
@Slf4j
public class ExportController {
    @Autowired
    private UserService userService;
    @Autowired
    private ProductInfoService productInfoService;
    @Resource
    private OrdersService ordersService;

    /**
     * 基础导出
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/base/export")
    public void export(HttpServletResponse response) throws IOException {
        LocalDate currentDate = LocalDate.now();
        // 定义格式：yyyyMMdd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);

        // 用户下载时的Excel表名
        String userTableName = "user_export_" + formattedDate;
        String fileName = URLEncoder.encode(userTableName, "UTF-8").replaceAll("\\+", "%20");

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()) + ".xlsx");

        // 暴露 Content-Disposition 头 设置后才能设置 Content-Disposition 到 Header 中
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        List<User> userList = userService.selectUserInfo();
        List<UserExcelVo> userExcelVoList = BeanCopyUtils.copyBeanList(userList, UserExcelVo.class);
        // Excel文件中的sheet名字
        String sheetName = "userSheetName";
        EasyExcel.write(response.getOutputStream(), UserExcelVo.class).sheet(sheetName).doWrite(userExcelVoList);
    }

    /**
     * 多Sheet导出
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/other/export")
    public void otherExport(HttpServletResponse response) throws IOException {
        LocalDate currentDate = LocalDate.now();
        // 定义格式：yyyyMMdd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);

        // 用户下载时的Excel表名
        String userTableName = "user_export_" + formattedDate;
        String fileName = URLEncoder.encode(userTableName, "UTF-8").replaceAll("\\+", "%20");

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()) + ".xlsx");

        // 暴露 Content-Disposition 头 设置后才能设置 Content-Disposition 到 Header 中
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        List<User> userList = userService.selectUserInfo();
        List<UserExcelVo> userExcelVoList = BeanCopyUtils.copyBeanList(userList, UserExcelVo.class);

        List<ProductInfo> productInfoList = productInfoService.list();
        // 使用 ExcelWriter 统一写入多个 Sheet
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()) {
            // 第一个 Sheet
            WriteSheet userSheet = EasyExcel.writerSheet("用户列表").head(UserExcelVo.class).build();
            excelWriter.write(userExcelVoList, userSheet);

            // 第二个 Sheet
            WriteSheet productSheet = EasyExcel.writerSheet("订单列表").head(ProductInfo.class).build();
            excelWriter.write(productInfoList, productSheet);
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
        }
    }

    /**
     * 模板导出
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/template/export")
    public void templateExport(HttpServletResponse response) throws IOException {
        LocalDate currentDate = LocalDate.now();
        // 定义格式：yyyyMMdd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);

        // 用户下载时的Excel表名
        String userTableName = "user_export_" + formattedDate;
        String fileName = URLEncoder.encode(userTableName, "UTF-8").replaceAll("\\+", "%20");

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()) + ".xlsx");

        // 暴露 Content-Disposition 头 设置后才能设置 Content-Disposition 到 Header 中
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        List<User> userList = userService.selectUserInfo();
        String exportTemplate = "D:\\Project\\test\\second-hand-market\\src\\main\\resources\\user_export.xlsx";

        List<UserExcelVo> userExcelVoList = BeanCopyUtils.copyBeanList(userList, UserExcelVo.class);
        // Excel文件中的sheet名字
        EasyExcel.write(response.getOutputStream(), UserExcelVo.class)
                .withTemplate(exportTemplate)
                .sheet()
                .doFill(userExcelVoList);
    }

    /**
     * 组合导出
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/combination/export")
    public void combinationExport(HttpServletResponse response) throws IOException {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);

        String userTableName = "user_export_" + formattedDate;
        String fileName = URLEncoder.encode(userTableName, "UTF-8").replaceAll("\\+", "%20");

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()) + ".xlsx");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        InputStream exportTemplate = new ClassPathResource("file/user_export.xlsx").getInputStream();
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(exportTemplate).build()) {
            FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            User user = userService.getByUserId("1892917359384326145");
            List<Orders> ordersList = ordersService.lambdaQuery().eq(Orders::getUserId, user.getId()).list();

            // 合并所有需要填充的数据
            Map<String, Object> data = new HashMap<>();
            data.put("userInfosName", user.getNickName());
            data.put("userTableTime", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
            data.put("userId", user.getId());
            data.put("userAvatar", user.getAvatar());
            data.put("userIntro", user.getIntro());
            data.put("userNickName", user.getNickName());
            data.put("userPhone", user.getPhone());
            data.put("userCreateTime", user.getCreateTime());

            // 订单表单创建时间
            data.put("orderTableTime", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));

            // 填充数据
            excelWriter.fill(data, writeSheet);

            // 填充订单列表
            List<OrderExcelVo> orderExcelVoList = BeanCopyUtils.copyBeanList(ordersList, OrderExcelVo.class);
            excelWriter.fill(orderExcelVoList, fillConfig, writeSheet);
        }
    }

    @PostMapping("/upload")
    @SneakyThrows
    public Result uploadExcel(MultipartFile file) {
        InputStream inputStream = file.getInputStream();
        UserInfoReadListener userInfoReadListener = new UserInfoReadListener(5, this::saveBatch);
        EasyExcel.read(inputStream, User.class, userInfoReadListener).sheet(0).doRead();
        if (userInfoReadListener.getReadErrorModel() != null) {
            log.info("读取错误：{}", userInfoReadListener.getReadErrorModel());
        } else {
            log.info("读取成功");
        }
        return Result.success();
    }

    private void saveBatch(List<User> userList) {
        log.info("批量插入条数：{}", userList.size());
        for (User item : userList) {
            log.info("item: {}", item);
        }
        for (User user : userList) {
            if (user.getId() == null) {
                user.setId(UUID.randomUUID().toString());
            }
        }
        // 自定义批量插入数据
        userService.insertBatch(userList);
    }
}